package com.yaolonga.itfc.manager.core.utils;

import cn.hutool.core.io.resource.ClassPathResource;
import com.yaolonga.itfc.manager.core.exception.CmdExecuteException;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

/**
 * @Author: yaolong
 * @CreateTime: 2024-11-24  13:08
 * @Description: TODO
 * @Version: 1.0
 */
@Slf4j
public class CommandUtils {

    public static String execClassPathShFileAndReturn(String file, ClassLoader classLoader) {
        return execClassPathShFileAndReturn(file, "", classLoader);
    }
    public static Process execClassPathShFile(String file,String args, ClassLoader classLoader) {
         ClassPathResource classPathResource = new ClassPathResource(file, classLoader);
        InputStream stream = classPathResource.getStream();
        // 创建临时文件
        File tempScriptFile = null;
        try {
            tempScriptFile = File.createTempFile("temp_script", ".sh");
            Files.copy(stream, tempScriptFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
            tempScriptFile.setExecutable(true);
            Process process = CommandUtils.execCmd("bash " + tempScriptFile.getAbsolutePath() + " " + args);
            tempScriptFile.deleteOnExit();
            return process;
        } catch (IOException e) {
            log.error("tmp file copy error", e);
            throw new RuntimeException(e);
        }

    }

    public static String execClassPathShFileAndReturn(String file, String args, ClassLoader classLoader) {
        ClassPathResource classPathResource = new ClassPathResource(file, classLoader);
        InputStream stream = classPathResource.getStream();
        // 创建临时文件
        File tempScriptFile = null;
        try {
            tempScriptFile = File.createTempFile("temp_script", ".sh");
            Files.copy(stream, tempScriptFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
            tempScriptFile.setExecutable(true);
            String s = CommandUtils.execCmdAndReturn("bash " + tempScriptFile.getAbsolutePath() + " " + args);
            tempScriptFile.deleteOnExit();
            return s;
        } catch (IOException e) {
            log.error("tmp file copy error", e);
            throw new RuntimeException(e);
        }
    }


    public static String execCmdAndReturn(String _commands) {
        String[] split = _commands.split("\\s+");
        return execCmdAndReturn(Arrays.asList(split));
    }

    public static String execCmdAndReturn(List<String> _commands) {
        return execCmdAndReturn(_commands, null);
    }

    public static String execCmdAndReturn(List<String> _commands, Consumer<OutputStream> inputCsm) {
        // 执行命令并获取结果
        try {
            ProcessBuilder processBuilder = new ProcessBuilder(_commands);
            Process process = processBuilder.start();
            // 获取命令的输入流和输出流
            OutputStream stdin = process.getOutputStream();
            InputStream stdout = process.getInputStream();
            InputStream stderr = process.getErrorStream();
            // 获取输出
            String output = readStream(stdout, Charset.defaultCharset());

            if (inputCsm != null) {
                inputCsm.accept(stdin);
            }
            // 等待进程结束
            int exitCode = process.waitFor();
            if (exitCode == 0) {
                return output;
            } else {
                String error = readStream(stderr, Charset.defaultCharset());
                if (Strings.isNotBlank(output)) {
                    throw new IOException(output);
                }
                throw new IOException("Command execution failed with exit code " + exitCode + " and error：" + error);
            }
        } catch (IOException e) {
            log.error("执行命令[{}]异常： {}", _commands, e.getMessage(), e);
            throw new CmdExecuteException(String.format("执行命令[%s]异常： %s", Strings.join(_commands, ' '), e.getMessage()), e);
        } catch (InterruptedException e) {
            throw new CmdExecuteException(Strings.join(_commands, ' '), e);
        }
    }


    public static Process execCmd(List<String> commands) {
        // 执行命令并获取结果
        try {
            ProcessBuilder processBuilder = new ProcessBuilder(commands);
            return processBuilder.start();
        } catch (IOException e) {
            log.error("执行命令[{}]异常： {}", commands, e.getMessage(), e);
            throw new CmdExecuteException(String.format("执行命令[%s]异常： %s", Strings.join(commands, ' '), e.getMessage()), e);
        }
    }

    public static String readStream(InputStream inputStream, Charset charset) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, charset));
        StringBuilder builder = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            builder.append(line);
            builder.append(System.getProperty("line.separator"));
        }
        return builder.toString();
    }

    public static Process execCmd(String cmd) {
        String[] split = cmd.split("\\s+");
        return execCmd(Arrays.asList(split));
    }


}
